package com.baoyouqun.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.fastjson2.JSONObject;
import com.baoyouqun.API.wx.BindWechatDTO;
import com.baoyouqun.API.wx.RegisterWechatDTO;
import com.baoyouqun.API.wx.WechatApiUtil;
import com.baoyouqun.base.utils.ConvertUtils;
import com.baoyouqun.domain.VO.UserVO;
import com.baoyouqun.entity.User;
import com.baoyouqun.service.UserService;
import com.baoyouqun.service.WechatLoginService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;

@Service
@Slf4j
public class WechatLoginServiceImpl implements WechatLoginService {

    // session_key有效期2小时（微信默认）
    private static final int SESSION_KEY_EXPIRE_SECONDS = 7200;
    @Resource
    private UserService userService;
    //    @Resource
//    private SmsService smsService;
    @Resource
    private WechatApiUtil wechatApiUtil;
    @Value("${wechat.appid}")
    private String appid;

    /**
     * 微信绑定现有账号
     */
    @Override
    public SingleResponse<String> bindWechat(BindWechatDTO bindWechatDTO) {
        try {
            // 1. 校验短信验证码
            boolean smsValid = true;
//                    smsService.verifySmsCode(
//                    bindWechatDTO.getCellphone(),
//                    bindWechatDTO.getSmsCode()
//            );
            if (!smsValid) {
                return SingleResponse.buildFailure("300001", "短信验证码错误或已过期");
            }

            // 2. 根据手机号查询用户
            User user = userService.selectByCellphone(bindWechatDTO.getCellphone());
            if (user == null) {
                return SingleResponse.buildFailure("300002", "该手机号未注册，请先注册");
            }

            // 3. 检查openid是否已被其他用户绑定
            if (userService.existsByWxOpenid(bindWechatDTO.getWxOpenid())) {
                return SingleResponse.buildFailure("300003", "该微信已绑定其他账号");
            }

            // 4. 更新用户微信信息
            user.setWxOpenid(bindWechatDTO.getWxOpenid());
            user.setWxSessionKey(bindWechatDTO.getWxSessionKey());
            user.setWxSessionExpire(LocalDateTime.now().plusMinutes(-1));
            userService.updateById(user);

            // 5. 生成登录Token
            StpUtil.login(user.getId());
            String token = StpUtil.getTokenValue();

            return SingleResponse.buildSuccess();
        } catch (Exception e) {
            log.error("微信绑定失败", e);
            return SingleResponse.buildFailure("300004", "微信绑定失败，请稍后重试");
        }
    }

    /**
     * 新用户微信注册绑定
     */
    @Override
    public SingleResponse<String> registerByWechat(RegisterWechatDTO registerWechatDTO) {
        try {
            // 1. 校验openid是否已绑定
            if (userService.existsByWxOpenid(registerWechatDTO.getWxOpenid())) {
                return SingleResponse.buildFailure("300005", "该微信已注册账号");
            }

            // 2. 若传入手机号，校验验证码并检查手机号是否已注册
            if (StringUtils.hasText(registerWechatDTO.getCellphone())) {
                // 校验验证码
                boolean smsValid = true;
//                smsService.verifySmsCode(
//                        registerWechatDTO.getCellphone(),
//                        registerWechatDTO.getSmsCode()
//                );
                if (!smsValid) {
                    return SingleResponse.buildFailure("300001", "短信验证码错误或已过期");
                }
                // 检查手机号是否已注册
                if (userService.existsByCellphone(registerWechatDTO.getCellphone())) {
                    return SingleResponse.buildFailure("300006", "该手机号已注册，请直接绑定");
                }
            }

            // 3. 创建新用户
            User newUser = new User();
            newUser.setWxOpenid(registerWechatDTO.getWxOpenid());
            newUser.setName(registerWechatDTO.getWxName());
            newUser.setHeadImg(registerWechatDTO.getWxAvatar());
            newUser.setCellphone(registerWechatDTO.getCellphone());
            newUser.setWxSessionKey(registerWechatDTO.getWxSessionKey()); // 可选存储
            newUser.setWxSessionExpire(LocalDateTime.now().plusHours(SESSION_KEY_EXPIRE_SECONDS));
            userService.save(newUser);

            // 4. 生成登录Token
            StpUtil.login(newUser.getId());
            String token = StpUtil.getTokenValue();

            return SingleResponse.of(token);
        } catch (Exception e) {
            log.error("微信注册失败", e);
            return SingleResponse.buildFailure("300007", "微信注册失败，请稍后重试");
        }
    }

    /**
     * 刷新微信session_key
     */
    @Override
    public SingleResponse<JSONObject> refreshWxSession(String refreshToken) {
        try {
            // 1. 校验登录状态
            if (!StpUtil.isLogin()) {
                return SingleResponse.buildFailure("401", "请先登录");
            }

            // 2. 调用微信接口刷新session_key
            JSONObject refreshResult = wechatApiUtil.refreshSessionKey(appid, refreshToken);
            if (refreshResult.containsKey("errcode") && refreshResult.getIntValue("errcode") != 0) {
                return SingleResponse.buildFailure("100810", "刷新session_key失败：" + refreshResult.getString("errmsg"));
            }

            // 3. 解析结果
            String newSessionKey = refreshResult.getString("session_key");
            String newRefreshToken = refreshResult.getString("refresh_token");
            String openid = refreshResult.getString("openid");

            // 4. 更新当前用户的session_key
            String userId = StpUtil.getLoginIdAsString();
            UserVO user = userService.selectById(userId);
            if (!openid.equals(user.getWxOpenid())) {
                return SingleResponse.buildFailure("403", "无权刷新该微信的session_key");
            }

            user.setWxSessionKey(newSessionKey);
            user.setWxSessionKey(newRefreshToken);
            user.setWxSessionExpire(LocalDateTime.now().plusHours(SESSION_KEY_EXPIRE_SECONDS));
            userService.updateById(ConvertUtils.copyBean(user, User.class));

            // 5. 返回新的session_key和refresh_token
            JSONObject result = new JSONObject();
            result.put("newSessionKey", newSessionKey);
            result.put("newRefreshToken", newRefreshToken);
            result.put("wxSessionExpire", user.getWxSessionExpire());

            return SingleResponse.of(result);
        } catch (Exception e) {
            log.error("刷新session_key异常", e);
            return SingleResponse.buildFailure("100811", "刷新session_key异常，请稍后重试");
        }
    }

    /**
     * 解除微信绑定
     */
    @Override
    public SingleResponse<Void> unbindWechat() {
        try {
            // 1. 校验登录状态
            if (!StpUtil.isLogin()) {
                return SingleResponse.buildFailure("401", "请先登录");
            }

            // 2. 清除用户微信信息
            String userId = StpUtil.getLoginIdAsString();
            UserVO user = userService.selectById(userId);
            user.setWxOpenid(null);
            user.setWxSessionKey(null);
            user.setWxSessionKey(null);
            user.setWxSessionExpire(null);
            userService.updateById(ConvertUtils.copyBean(user, User.class));

            return SingleResponse.buildSuccess();
        } catch (Exception e) {
            log.error("微信解绑失败", e);
            return SingleResponse.buildFailure("300008", "微信解绑失败，请稍后重试");
        }
    }
}
